package org.academic.texteditor.gui.component;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragSource;

import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.Style;
import javax.swing.text.StyledDocument;

import org.academic.texteditor.gui.component.listener.DragCopyTextListener;
import org.academic.texteditor.gui.component.toolbar.ToolBarFactory;
import org.academic.texteditor.gui.helper.ParagraphElement;
import org.edkits.LaTeXEditorKit;

public class PersonalizedTextPane extends JTextPane {

	private static final long serialVersionUID = 3640146647727073040L;

	public PersonalizedTextPane() {
		setDropTarget(null);
		setEditorKit(new LaTeXEditorKit());
		
		DragSource dragSource = DragSource.getDefaultDragSource();
		dragSource.createDefaultDragGestureRecognizer(ToolBarFactory.getClipBoard(), DnDConstants.ACTION_COPY_OR_MOVE, new DragCopyTextListener(this));
	}
	
	public void applyStyleParagraph(String styleName) {
		StyledDocument doc = getStyledDocument();
		Element element = doc.getParagraphElement(getCaretPosition());
		
		doc.setParagraphAttributes(element.getStartOffset(), element.getEndOffset() - element.getStartOffset(), getStyle(styleName), true);
	}

	public boolean isStyleParagraph(String name) {
		StyledDocument doc = getStyledDocument();
		Element element = doc.getParagraphElement(getCaretPosition());
		Object styleName = element.getAttributes().getAttribute(AttributeSet.NameAttribute);
		
		return styleName.equals(name);
	}

	public void applyStyleCharacter(String styleName) {
		StyledDocument doc = getStyledDocument();
		Element element = doc.getCharacterElement(getCaretPosition());
		
		doc.setCharacterAttributes(element.getStartOffset(), element.getEndOffset() - element.getStartOffset(), getStyle(styleName), true);
	}
	
	public boolean isStyleCharacter(String name) {
		StyledDocument doc = getStyledDocument();
		Element element = doc.getCharacterElement(getCaretPosition());
		Object styleName = element.getAttributes().getAttribute(AttributeSet.NameAttribute);
		
		return styleName.equals(name);
	}
	
	public Style getStyleParagraph() {
		return getLogicalStyle();
	}
	
	public void removeStyleParagraph() {
		ParagraphElement element = getParagraphElement();
		
		StyledDocument doc = getStyledDocument();
		doc.setCharacterAttributes(element.getStartOffset(), element.getEndOffset() - element.getStartOffset(), getStyle("default"), true);
	}
	
	public void insert(int offset, String text) {
		Document doc = getDocument();
		try {
			doc.insertString(offset, text, null);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}
	
	public void removeParagraph() {
		removeParagraph(getParagraphNumber());
	}
	
	public void removeParagraph(int paragraphNumber) {
		ParagraphElement paragraphElement = getParagraphElement(paragraphNumber);
		int startOffset = paragraphElement.getStartOffset();
		int endOffset = paragraphElement.getEndOffset();
		int length = endOffset - startOffset;
		
		if (getParagraphCount() == paragraphNumber + 1) {
			startOffset--;
			if (startOffset < 0) {
				startOffset = 0;
				length--;
			}
		}

		Document doc = getDocument();
		try {
			doc.remove(startOffset, length);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}
	}

	public String getParagraph() {
		return getParagraph(getParagraphNumber());
	}
	
	public String getParagraph(int paragraphNumber) {
		ParagraphElement paragraphElement = getParagraphElement(paragraphNumber);
		if (paragraphElement == null) {
			return null;
		}
		
		return paragraphElement.getText();
	}

	public int getParagraphCount() {
		Element root = getDocument().getDefaultRootElement();
		return root.getElementCount();
	}
	
	public int getParagraphNumber() {
		int position = getCaretPosition();
		Element root = getDocument().getDefaultRootElement();
		int line = root.getElementIndex(position);
		return line;
	}

	public ParagraphElement getParagraphElement() {
		return getParagraphElement(getParagraphNumber());
	}

	public ParagraphElement getParagraphElement(int paragraphNumber) {
		Document doc = getDocument();
		Element root = doc.getDefaultRootElement();
		Element element = root.getElement(paragraphNumber);
		int startOffset = element.getStartOffset();
		int endOffset = element.getEndOffset();

		String text = null;
		try {
			text = doc.getText(startOffset, endOffset - startOffset - 1);
		} catch (BadLocationException e) {
			e.printStackTrace();
		}

		ParagraphElement paragraphElement = new ParagraphElement();
		paragraphElement.setIndex(paragraphNumber);
		paragraphElement.setStartOffset(startOffset);
		paragraphElement.setEndOffset(endOffset);
		paragraphElement.setText(text);
		return paragraphElement ;
	}

	@Override
	public void paint(Graphics g) {
		Graphics2D g2d = (Graphics2D) g;
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
		
		super.paint(g2d);
	}
	
}
